This document demonstrates how to group and merge visium spots with low coverage using https://github.com/iaaka/visutils The spots are grouped into coarser mesh by seven spots preserving hexagonal layout. All spots from single groups with coverage below certain threshold are merged, their counts are summed and on spot is used as the representative: either the central one (if its coverage below the threshold) or the spot with highest coverage.
First lets install the package, you need to do it only once
devtools::install_github("iaaka/visutils",force = TRUE)
## Using github PAT from envvar GITHUB_PAT
## Downloading GitHub repo iaaka/visutils@HEAD
##
##
checking for file ‘/tmp/RtmpXX0swB/remotes11d8375ad57c/iaaka-visutils-676ab4e/DESCRIPTION’ ...
✔ checking for file ‘/tmp/RtmpXX0swB/remotes11d8375ad57c/iaaka-visutils-676ab4e/DESCRIPTION’
##
─ preparing ‘visutils’:
## checking DESCRIPTION meta-information ...
✔ checking DESCRIPTION meta-information
##
─ checking for LF line-endings in source and make files and shell scripts
##
─ checking for empty or unneeded directories
##
─ building ‘visutils_0.0.0.9000.tar.gz’
##
##
## Installing package into '/home/jovyan/R/x86_64-pc-linux-gnu-library/4.0'
## (as 'lib' is unspecified)
library(visutils)
library(Seurat)
## Warning: package 'Seurat' was built under R version 4.0.5
## Attaching SeuratObject
## Attaching sp
loadVisiumFrom10x("https://cf.10xgenomics.com/samples/spatial-exp/1.3.0","Visium_Mouse_Olfactory_Bulb",outdir="data")
mob = Load10X_Spatial('data/Visium_Mouse_Olfactory_Bulb/')
SpatialFeaturePlot(mob,'nCount_Spatial')
# Quick start everything can be done just in one line
umi.thr = 20000
mobm0 = mergeSpots(mob,getCenters(mob,to.merge = mob$nCount_Spatial<umi.thr))
# lets compare merged object mobm0 with the original one
cex = scaleTo(sqrt(mobm0$nspots),1,sqrt(8),minx = 1,maxx = sqrt(7))*0.9
SpatialFeaturePlot(mob,'nCount_Spatial') + SpatialFeaturePlot(mobm0,'nCount_Spatial',pt.size.factor = cex*2)
Chose coverage threshold
hist(mob$nCount_Spatial,100)
table(mob$nCount_Spatial<20000)
##
## FALSE TRUE
## 457 728
This sample has good coverge and it is not very reasonable to group spots here. However for demonstration purposes I’ll merge all the spots with coverage less than 20000 UMIs. Normally this threshold should be about 500-1000.
groups = getCenters(mob,to.merge = mob$nCount_Spatial<20000)
groups[1:5,]
## tissue row col imagerow imagecol group group.row group.col
## AAACAAGTATCTCCCA-1 1 50 102 2887 6022 49_101 49 101
## AAACCGGGTAGGTACC-1 1 42 28 7078 5238 42_28 42 28
## AAACCGTTCGTCCAGG-1 1 52 42 6284 6223 52_42 52 42
## AAACGAGACGGTTGAT-1 1 35 79 4191 4546 35_79 35 79
## AAACTGCTGGCTCCAA-1 1 45 67 4869 5532 45_67 45 67
mob$group = groups$group
mob@meta.data[1:5,]
## orig.ident nCount_Spatial nFeature_Spatial group
## AAACAAGTATCTCCCA-1 SeuratProject 1055 642 49_101
## AAACCGGGTAGGTACC-1 SeuratProject 31271 6471 42_28
## AAACCGTTCGTCCAGG-1 SeuratProject 31855 6674 52_42
## AAACGAGACGGTTGAT-1 SeuratProject 30391 6803 35_79
## AAACTGCTGGCTCCAA-1 SeuratProject 25989 6610 45_67
Here I color spots that are going to be merged by same color. Note that some of them form hexagons (when all spots have coverage below threshold) and some groups are smaller or even singletons
SpatialPlot(mob,'group',cols = char2col(mob$group,palette = TRUE),pt.size.factor = 2) +NoLegend()
Lets use visutils visualisations since it is a bit cleare (specificall hex one)
par(mfrow=c(1,2),mar=c(1,1,1,1))
plotVisium(mob,mob$group,plot.legend = F)
plotVisium(mob,mob$group,plot.legend = F,type='hex')
Now we have groups, lets use them to merge spots
mobm = mergeSpots(mob,groups)
mobm@meta.data[1:5,]
## orig.ident nCount_Spatial nFeature_Spatial group nspots
## GTGGGCTTAGACACAC-1 SeuratProject 1851 1079 28_38 1
## TGTATAACAGATCCTG-1 SeuratProject 8317 3467 28_80 2
## CCTGGCTAGACCCGCC-1 SeuratProject 35378 7453 29_43 5
## CGAGGCTAAATATGGC-1 SeuratProject 31508 7151 29_71 4
## CCACAATGTACGTCTT-1 SeuratProject 21209 5958 29_85 4
## merged_spots
## GTGGGCTTAGACACAC-1 GTGGGCTTAGACACAC-1
## TGTATAACAGATCCTG-1 TGCATGTGGTAATCTA-1;TGTATAACAGATCCTG-1
## CCTGGCTAGACCCGCC-1 CCTGGCTAGACCCGCC-1;TCAGGTTCTTTGAGAA-1;TCGAAATTTAGGACCA-1;TGGAGTGATGCGATGA-1;TTAAGCGCCTGACCCA-1
## CGAGGCTAAATATGGC-1 CGAGAGATGTGAACCT-1;CGAGGCTAAATATGGC-1;GACACAAGGGAAGAAA-1;GGCAATAGTCAATGAG-1
## CCACAATGTACGTCTT-1 ACCCAACGCCCGTGGC-1;CCACAATGTACGTCTT-1;GAGCTAAGGGCATATC-1;TGAGTGGTCCGTGACG-1
The resultant seurat object contains summed counts, metadata table provides informatin about number of spots merged (nspots) and their identity (merged_spots)
par(mar=c(1,1,1,5))
cex = scaleTo(sqrt(mobm$nspots),1,sqrt(8),minx = 1,maxx = sqrt(7))*0.9
#plotVisium(mobm,mobm$nCount_Spatial,zfun = log1p,cex=cex)
SpatialFeaturePlot(mob,'nCount_Spatial') + SpatialFeaturePlot(mobm,'nCount_Spatial',pt.size.factor = cex*2)